package timing.ukulele.user.util;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Unmarshaller;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

/**
 * 微信公众号工具
 */
public class WeiXinMpUtil {
    public static boolean checkSignature(String signature, String timestamp, String nonce, String token) {
        //从请求中（也就是微信服务器传过来的）拿到的token, timestamp, nonce
        String[] arr = new String[]{token, timestamp, nonce};
        // 将token、timestamp、nonce三个参数进行字典序排序
        sort(arr);
        StringBuilder content = new StringBuilder();
        for (String s : arr) {
            content.append(s);
        }
        MessageDigest md;
        String tmpStr = null;
        try {
            md = MessageDigest.getInstance("SHA-1");
            // 将三个参数字符串拼接成一个字符串进行sha1加密
            byte[] digest = md.digest(content.toString().getBytes());
            //将字节数组转成字符串
            tmpStr = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        content = null;
        // 将sha1加密后的字符串可与signature对比，标识该请求来源于微信
        return tmpStr != null && tmpStr.equals(signature.toUpperCase());
    }

    //将加密后的字节数组变成字符串
    private static String byteToStr(byte[] byteArray) {
        StringBuilder strDigest = new StringBuilder();
        for (byte b : byteArray) {
            strDigest.append(byteToHexStr(b));
        }
        return strDigest.toString();
    }

    private static String byteToHexStr(byte mByte) {
        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];

        return new String(tempArr);
    }

    //用于字典排序
    public static void sort(String[] a) {
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = i + 1; j < a.length; j++) {
                if (a[j].compareTo(a[i]) < 0) {
                    String temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
    }

    public static <T> T convertToObject(String xml, Class<T> clazz) {
        T _clazz;
        StringReader reader = null;
        try {
            JAXBContext context = JAXBContext.newInstance(clazz);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            reader = new StringReader(xml);
            _clazz = (T) unmarshaller.unmarshal(reader);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        return _clazz;
    }
    /**
     * map转xml格式
     * @param paramsMap 要转换的map
     * @return xml字符串
     */
    public static String mapToXml(Map<String, String> paramsMap) {
        StringBuilder sb = new StringBuilder("<xml>");
        for (String key : paramsMap.keySet()) {
            String value = paramsMap.get(key);
            sb.append("<").append(key).append(">");
            sb.append(value);
            sb.append("</").append(key).append(">");
        }
        sb.append("</xml>");
        return sb.toString();
    }

    public static String getContentData(String path) {
        InputStream ins = WeiXinMpUtil.class.getClassLoader().getResourceAsStream(path);
        if (ins == null) {
            return "";
        }
        try {
            BufferedReader tBufferedReader = new BufferedReader(new InputStreamReader(ins));
            StringBuilder tStringBuffer = new StringBuilder();
            String sTempOneLine;
            while ((sTempOneLine = tBufferedReader.readLine()) != null) {
                tStringBuffer.append(sTempOneLine);
            }
            return tStringBuffer.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "";
    }
}
